import { Controller } from 'egg';
import validateInput from '../decorator/inputValidate'
const userCreateRules = {
  username: 'email',
  password: { type: 'password', min: 8 }
}
const sendCodeRules = {
  phoneNumber: {
    type: 'string',
    format: /^1[3-9]\d{9}$/,
    message: '手机号格式错误'
  }
}
export default class UserController extends Controller {
  async createByEmail() {
    const { ctx, service, app } = this;
    // 对传入的数据进行验证
    // ctx.validate(userCreateRules) 简单方式
    const errors = this.validateFun(userCreateRules)
    if (errors) {
      return ctx.helper.error({ ctx, errorType: 'UserValidateFail' });
    }
    // 验证用户名称的唯一性
    const { username } = ctx.request.body;
    const user = await service.user.findByUsername(username)
    ctx.logger.info('get', user)
    if (user) {
      return ctx.helper.error({ ctx, errorType: 'createUserAlreadyExists' });
    }
    // 成功新增用户
    const userData = await service.user.createByEmail(ctx.request.body);
    ctx.helper.success({ ctx, res: userData });
  }

  /**
   * 统一验证方法
   * @param rules
   * @return
   */
  validateFun(rules: any) {
    const { ctx, app } = this;
    // 对传入的数据进行验证
    // ctx.validate(userCreateRules) 简单方式
    const errors = app.validator.validate(rules, ctx.request.body);
    ctx.logger.warn(errors)// 打印出错误信息
    return errors
  }
  @validateInput(sendCodeRules, 'UserValidateFail')
  async sendveriCode() {
    const { ctx, app } = this;
    const { phoneNumber } = ctx.request.body;

    const preVeriCode = await app.redis.get(`phoneVeriCode-${phoneNumber}`) // 获取手机验证码

    if (preVeriCode) {
      // 如果存在验证码
      return ctx.helper.error({ ctx, errorType: 'sendVeriCodeFrequentlyFailInfo' })
    }

    // 模拟生成一个code值
    const veriCode = (Math.floor(((Math.random() * 9000) + 1000))).toString();
    ctx.logger.info('phoneNumber', phoneNumber, veriCode)
    await app.redis.set(`phoneVeriCode-${phoneNumber}`, veriCode, 'ex', 60)
    ctx.helper.success({ ctx, res: { veriCode } })
  }

  @validateInput(userCreateRules, 'UserValidateFail')
  async loginByEmail() {
    const { ctx, service, app } = this;
    const { username, password, _id } = ctx.request.body;
    const userDate = await service.user.findByUsername(username);
    if (!userDate) {
      return ctx.helper.error({ ctx, errorType: 'loginCheckFailInfo' })
    }
    const verifyPwd = await ctx.compare(password, userDate.password);
    if (!verifyPwd) {
      return ctx.helper.error({ ctx, errorType: 'loginCheckFailInfo' })
    }
    const token = app.jwt.sign({ username, _id }, app.config.jwt.secret, { expiresIn: 60 * 60 })
    ctx.helper.success({ ctx, res: { token }, msg: '登录成功' })
  }
  @validateInput(sendCodeRules, 'UserValidateFail')
  async loginByCellphone() {
    const { ctx, app, service } = this;
    const { phoneNumber, veriCode } = ctx.request.body;
    const preVeriCode = await app.redis.get(`phoneVeriCode-${phoneNumber}`) // 获取手机验证码
    if (veriCode !== preVeriCode) {
      return ctx.helper.error({ ctx, errorType: 'validataVeriCode' })
    }
    // 获取登录tocken
    const token = await service.user.loginByCellPhone();
    ctx.helper.success({ ctx, res: { token }, msg: '登录成功' })
  }

  async oauth() {
    const { app, ctx } = this;
    const { cid, redirectURL } = app.config.giteeOauthConfig;
    ctx.redirect(`https://gitee.com/oauth/authorize?client_id=${cid}&redirect_uri=${redirectURL}&response_type=code`)
  }

  async oauthByGitee() {
    const { ctx, app } = this;
    const { code } = ctx.request.query;
    try {
      const token = await ctx.service.user.loginByGitee(code);
      ctx.helper.success({ ctx, res: { token }, msg: '登录成功' })
    } catch (error) {
      ctx.helper.error({ ctx, errorType: 'oauthGiteeError' })
    }
  }
  /**
   * 通过id获取用户信息
   */
  async show() {
    const { ctx, service } = this;
    const userData = await service.user.findByUsername(ctx.state.user.username)
    ctx.helper.success({ ctx, res: userData?.toJSON(), msg: '获取用户信息成功' })
  }
}
